App.require(["htmlTool"], function (htmlTool) {
    var app = App.getCurrent();

    app.defineComponent("str-select", {
        render: function (next) {
            this.computeData();
            this.fetch("./index.html", function (text) {
                next(this.renderHTML(text));
            })
        },
        getDomObj: function () {
            this.attachDom("#textarea", "textField")
                .attachDom("#list", "list")
                .attachDom('[role="dropdown"]', "container")
                .attachDom("#clear", "clearIcon")
                .attachEvent("clearIcon", "iconclick", this.clearHandler, false)
                .attachEvent("list", "menuitemclick", this.menuclickHandler, false)
                .attachEvent("list", "menuitemchange", this.changeHandler, false)
                .attachEvent("textField", "textfocus", this.textFocusHandler, false)
                // .attachEvent("textField", "textblur", this.blur, false);
        },
        _focus: function () {
            if (this.property.readonly) return;
            var container = this.domList.container;
            var height = window.innerHeight,
                rect = container.getBoundingClientRect();
            container.removeAttribute("status");
            container.setAttribute("show", "true");
            if (height - rect.bottom < 144) container.setAttribute("status", "up");
            this.addEvent();
        },
        textFocusHandler: function (ev) {
            this._focus(ev);
            this.dispatchCustomEvent("selectfocus", {
                component: this,
                event: ev
            });
        },
        focus: function () {
            this.domList.textField.focus();
            this._focus();
        },
        blur: function () {
            // var container = this.domList.container;
            // container.setAttribute("status", "hidden");
            // this.domList.textField.removeEdit();
            this.removeEvent();
        },
        removeEvent: function () {
            this.data.isAddEvent = false;
            this.domList.container.removeEventListener("click", this.clickContainerHandler, false);
            // this.domList.textField.nodes[0].removeEventListener("textblur", this.blurHandler, false);
            window.removeEventListener("click", this.clickDocHandler, false);
            this.domList.list.removeKeyboard();
            // document.documentElement.classList.remove("clickable")
        },
        addEvent: function () {
            if (this.data.isAddEvent) return;
            this.data.oldValue = this.property.value;
            this.data.isAddEvent = true;
            this.domList.container.addEventListener("click", this.clickContainerHandler, false);
            // this.domList.textField.nodes[0].addEventListener("textblur", this.blurHandler, false);
            window.addEventListener("click", this.clickDocHandler, false);
            this.domList.list.setKeyboard();
            // document.documentElement.classList.add("clickable")
            
        },
        _clickContainerHandler: function (ev) {
            this.data.isClick = true;
        },
        _clickDocHandler: function (ev) {
            if (!this.data.isClick) {
                var container = this.domList.container;
                container.removeAttribute("show");
                // this.domList.textField.removeEdit();
                this.removeEvent();
                this.dispatchCustomEvent("selectblur", {
                    component: this,
                    event: ev
                });
                // console.log(container.className);
                if (!this.isSameValue()) {
                    this.dispatchCustomEvent("selectchange", {
                        component: this,
                        event: ev
                    });
                }
            }
            this.data.isClick = false;
        },
        addOption: function (value, content, property) {
            this.domList.list.appendOption(value, content, property);
        },
        removeOption: function (value) {
            this.domList.list.removeOption(value);
            if (this.property.multiple) {
                var index = this.property.value.indexOf(value);
                if (index !== -1) {
                    this.property.value.splice(index, 1);
                    this.data.value.splice(index, 1);
                }
            }
            else {
                if (this.property.value === value) {
                    this.property.value = "";
                    this.data.value = {};
                }
            }
        },
        reset: function () {
            this.domList.list.reset();
            this.domList.textField.reset();
            this.property.value = this.data.defaultedValue;
            this.computeValueContent();
        },
        isSameValue: function () {
            var oldValue = this.data.oldValue, currentValue = this.property.value;
            if (this.property.multiple) {
                if (oldValue.length !== currentValue.length) return false;
                for (var i = 0; i < oldValue.length; i++) {
                    if (currentValue.indexOf(oldValue[i]) === -1) return false;
                }
                return true;
            }
            else {
                return oldValue === currentValue;
            }
        },
        changeHandler: function (ev) {
            var value = ev.detail.value;
            this.data.value = value;
            this.property.value = value.map(function (item) {
                return item.value;
            });
            this.domList.textField.value = this.computedValue(value);
        },
        computedValue: function (list) {
            var result = [];
            for (var i = 0; i < list.length; i++) {
                result.push(list[i].content)
            }
            return result.join("; ");
        },
        menuclickHandler: function (ev) {
            var value = ev.detail.value,
                textField = this.domList.textField;

            if (!this.property.multiple) {
                this.data.value = value;
                this.property.value = value.value;
                textField.value = value.content;
                // textField.removeEdit();
                var container = this.domList.container;
                container.setAttribute("status", "hidden");
                container.removeAttribute("show");
                this.removeEvent();
                this.dispatchCustomEvent("selectblur", {
                    component: this,
                    event: ev
                });
                if (!this.isSameValue()) {
                    this.dispatchCustomEvent("selectchange", {
                        component: this, event: ev
                    });
                }
            }
        },
        clearHandler: function (ev) {
            var textField = this.domList.textField;
            textField.value = "";
            textField.removeEdit();
            this.domList.list.reset();
            if (this.property.multiple) {
                this.data.value = [];
                this.property.value = [];
            }
            else {
                this.data.value = {};
                this.property.value = "";
            }
            var container = this.domList.container;
            container.setAttribute("status", "hidden");
            this.removeEvent();
            this.dispatchCustomEvent("selectclear", {
                component: this,
                event: ev
            })
        },
        init: function () {
            this.clickContainerHandler = this._clickContainerHandler.bind(this);
            this.clickDocHandler = this._clickDocHandler.bind(this);
            this.blurHandler = this.blur.bind(this);
            this.data.isClick = false;
            this.computeValueContent();
        },
        computeValueContent: function () {
            var property = this.property, list = this.domList.list, 
                optionlist = list.getOptions(), value = property.value;
            if (property.multiple) {
                this.data.value = [];
                if (value.length == 0) return;
                var content = [];
                for (var i = 0; i < value.length; i++) {
                    var option = list._getOptionByValue(value[i]);
                    if (option) {
                        content.push(option.content);
                        list.setChecked(value[i], true);
                        this.data.value.push({
                            value: value[i],
                            content: option.content
                        })
                    }
                }
                this.domList.textField.value = content.join("; ");
            }
            else {
                this.data.value = {};
                if (!value) return;
                var i, len = optionlist.length;
                for (i = 0; i < len; i++) {
                    if (optionlist[i].value === value) break;
                }
                if (i === len) i = 0;
                this.domList.textField.value = optionlist[i].content;
                this.property.value = optionlist[i].value;
                this.data.value = {
                    value: optionlist[i].value,
                    content: optionlist[i].content
                };
            }   
        },
        computeData: function () {
            var property = this.property;
            property.required = typeof property.required !== "undefined" ? "required" : "";
            property.readonly = typeof property.readonly !== "undefined" ? "readonly" : "";
            property.disabled = typeof property.disabled !== "undefined" ? "disabled" : "";
            property.name = property.name || this.uid;
            property.label = property.label || property.name;
            property.form = property.form || "";
            property.placeholder = property.placeholder || "";
            property.rendertype = property.rendertype || "filled";
            property.size = property.size || "normal";
            property.type = property.type || "single";
            property.value = property.value || "";
            this.data.defaultedValue = property.value;
            property.optionlist = this.slot;
            property.multiple = typeof property.multiple !== "undefined" ? "multiple" : "";
            property.assistivetype = property.assistivetype || "";
            property.assistivetext = property.assistivetext || "";
            property.leadicon = property.leadicon || "";
            property.trailicon = property.trailicon || "";
            property.class = property.class || "";
            property.value = property.value || "";
            if (property.multiple) {
                property.value = property.value.split(/;\s+/).filter(function (item) {
                    return item !== "";
                })
            }
            property.hiddenbottom = typeof property.hiddenbottom !== "undefined" ? "hiddenbottom" : "";
            this.data.propertystr = this.createPropertyStr({
                class: property.class,
                trailicon: property.trailicon,
                leadicon: property.leadicon,
                size: property.size,
                status: "hidden"
            })
        },
        get className() {
            return this.property.class;
        },
        set className(value) {
            if (this.property.class === value) return;
            this.domList.container.className = value;
            this.property.class = value;
        },
        get hiddenbottom() {
            return this.property.hiddenbottom;
        },
        set hiddenbottom(value) {
            value = value === "hiddenbottom" ? "hiddenbottom" : "";
            if (value === this.property.hiddenbottom) return;
            this.property.hiddenbottom = value;
            this.domList.textField.hiddenbottom = value;
        },
        get trailicon() {
            return this.property.trailicon;
        },
        set trailicon(value) {
            if (this.property.trailicon === value) return;
            this.property.trailicon = value;
            this.domList.textField.trailicon = value;
        },
        get leadicon() {
            return this.property.leadicon;
        },
        set leadicon(value) {
            if (this.property.leadicon === value) return;
            this.property.leadicon = value;
            this.domList.textField.leadicon = value;
        },
        get assistivetext() {
            return this.property.assistivetext;
        },
        get assistivetype() {
            return this.property.assistivetype;
        },
        get assistive() {
            var property = this.property;
            return {
                type: property.assistivetype,
                text: property.assistivetext
            }
        },
        set assistive(obj) {
            this.property.assistivetype = obj.type;
            this.property.assistivetext = obj.text;
            this.domList.textField.assistivetext = obj;
        },
        get value() {
            return this.property.value;
        },
        set value(val) {
            if (this.property.value === val) return;
            this.property.value = val;
            this.computeValueContent();
        },
        get multiple() {
            return this.property.multiple;
        },
        set multiple(value) {
            value = value ? "multiple" : "";
            if (this.property.multiple === value) return;
            
            var textField = this.domList.textField, list = this.domList.list;
            list.multiple = value;
            if (value) {
                var oldValue = this.property.value;
                this.property.value = [this.property.value];
                var optionlist = list.getOptions();
                for (var i = 0; i < optionlist.length; i++) {
                    if (optionlist[i].value === oldValue) {
                        textField.value = optionlist[i].content + "; ";
                        break;
                    }
                }
            }
            else {
                var values = list.getCheckedValues();
                this.property.value = values[0].value;
                textFocusHandler.value = values[0].content;
            }
            this.property.multiple = value;
        },
        get rendertype() {
            return this.property.rendertype;
        },
        set rendertype(value) {
            value = value === "outline" ? "outline" : "filled";
            if (value === this.property.rendertype) return;
            this.property.rendertype = value;
            this.domList.textField.rendertype = value;
        },
        get size() {
            return this.property.size;
        },
        set size(value) {
            value = value === "small" ? "small" : "normal";
            if (value === this.property.size) return;
            this.domList.container.setAttribute("size", value);
            this.property.size = value;
            this.domList.textField.size = value;
        },
        get placeholder() {
            return this.property.placeholder;
        },
        set placeholder(value) {
            this.domList.textField.placeholder = value;
            this.property.placeholder = value;
        },
        get form() {
            return this.property.form;
        },
        set form(value) {
            this.property.form = value;
            this.domList.textField.form = value;
        },
        get label() {
            return this.property.label;
        },
        set label(value) {
            this.property.label = value;
            this.domList.textField.label = value;
        },
        set name(value) {
            if (this.property.name === value) return;
            this.property.name = value;
            this.domList.textField.name = value;
        },
        get name() {
            return this.property.name;
        },
        set readonly(value) {
            this.property.readonly = value;
        },
        get readonly() {
            return this.property.readonly;
        },
        get disabled() {
            return this.property.disabled;
        },
        set disabled(value) {
            value = value ? "disabled" : "";
            if (this.property.disabled === value) return;
            this.property.disabled = value;
            this.domList.textField.disabled = value;
        },
        get required() {
            return this.property.required;
        },
        set required(value) {
            value = value ? "required" : "";
            if (this.property.required === value) return;
            this.property.required = value;
            this.domList.textField.required = value;
        }
    })
})